﻿using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ThridGroup.ERP.DTO.ProductionSystemDto.IncomingInspectionDto;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using ClosedXML.Excel;

namespace ThridGroup.ERP.ProductionSystem
{
    public class ncomingInspectionServices : ApplicationService, IncomingInspectionServices
    {
        private readonly IRepository<IncomingInspection, int> _incomingInspectionrepository;

        public ncomingInspectionServices(IRepository<IncomingInspection, int> incomingInspectionrepository) 
        {
           _incomingInspectionrepository = incomingInspectionrepository;
        }
        /// <summary>
        /// 添加来料检验
        /// </summary>
        /// <param name="createIncomingInspectionDto"></param>
        /// <returns></returns>
        public  async Task<int> AddIncomingInspection(CreateIncomingInspectionDto createIncomingInspectionDto)
        {
            var result = ObjectMapper.Map<CreateIncomingInspectionDto, IncomingInspection>(createIncomingInspectionDto);
            await _incomingInspectionrepository.InsertAsync(result);
            return result.Id;
        }

        /// <summary>
        /// 分页及多条件查询来料检验列表
        /// </summary>
        /// <param name="page">页码</param>
        /// <param name="limit">每页数量</param>
        /// <param name="incomingInspectionCode">来料检验单编号（模糊查询）</param>
        /// <param name="batch">供应商批次号（模糊查询）</param>
        /// <param name="testingResult">检测结果（等值查询）</param>
        /// <param name="testingPerson">检测人员（模糊查询）</param>
        /// <param name="productName">产品物料名称（模糊查询）</param>
        /// <param name="incomingDate">来料日期（等值查询）</param>
        /// <param name="testingDate">检测日期（等值查询）</param>
        /// <returns>分页后的来料检验列表</returns>
        public async Task<PagedResultDto<IncomingInspectionListDto>> GetIncomingInspectionList(int page, int limit, string incomingInspectionCode = null, string batch = null, string testingResult = null, string testingPerson = null, string productName = null, DateTime? incomingDate = null, DateTime? testingDate = null)
        {
            var query = await _incomingInspectionrepository.GetQueryableAsync();

            if (!string.IsNullOrWhiteSpace(incomingInspectionCode))
                query = query.Where(x => x.IncomingInspectionCode.Contains(incomingInspectionCode));
            if (!string.IsNullOrWhiteSpace(batch))
                query = query.Where(x => x.Batch.Contains(batch));
            if (!string.IsNullOrWhiteSpace(testingResult))
                query = query.Where(x => x.TestingResult == testingResult);
            if (!string.IsNullOrWhiteSpace(testingPerson))
                query = query.Where(x => x.TestingPerson.Contains(testingPerson));
            if (!string.IsNullOrWhiteSpace(productName))
                query = query.Where(x => x.ProductName.Contains(productName));
            if (incomingDate.HasValue)
                query = query.Where(x => x.IncomingDate.Date == incomingDate.Value.Date);
            if (testingDate.HasValue)
                query = query.Where(x => x.TestingDate.Date == testingDate.Value.Date);

            var totalCount = await query.CountAsync();
            var items = await query
                .OrderByDescending(x => x.Id)
                .Skip((page - 1) * limit)

                .Take(limit)
                .ToListAsync();

            var dtos = ObjectMapper.Map<List<IncomingInspection>, List<IncomingInspectionListDto>>(items);
            return new PagedResultDto<IncomingInspectionListDto>(totalCount, dtos);
        }

        /// <summary>
        /// 批量删除来料检验
        /// </summary>
        /// <param name="ids">要删除的ID集合</param>
        public async Task BatchDeleteAsync(List<int> ids)
        {
            await _incomingInspectionrepository.DeleteDirectAsync(x => ids.Contains(x.Id));
        }

        /// <summary>
        /// 根据ID获取来料检验详情（反填）
        /// </summary>
        /// <param name="id">主键ID</param>
        public async Task<IncomingInspectionListDto> GetByIdAsync(int id)
        {
            var entity = await _incomingInspectionrepository.GetAsync(id);
            return ObjectMapper.Map<IncomingInspection, IncomingInspectionListDto>(entity);
        }

        /// <summary>
        /// 删除单条来料检验
        /// </summary>
        /// <param name="id">主键ID</param>
        public async Task DeleteAsync(int id)
        {
            await _incomingInspectionrepository.DeleteAsync(id);
        }

        /// <summary>
        /// 修改单条来料检验
        /// </summary>
        /// <param name="dto">要修改的来料检验DTO</param>
        public async Task UpdateAsync(CreateIncomingInspectionDto dto)
        {
            var entity = await _incomingInspectionrepository.GetAsync(dto.Id);
            ObjectMapper.Map(dto, entity);
            await _incomingInspectionrepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 导出来料检验数据（Excel格式）
        /// </summary>
        /// <param name="incomingInspectionCode">来料检验单编号</param>
        /// <param name="batch">供应商批次号</param>
        /// <param name="testingResult">检测结果</param>
        /// <param name="testingPerson">检测人员</param>
        /// <param name="productName">产品物料名称</param>
        /// <param name="incomingDate">来料日期</param>
        /// <param name="testingDate">检测日期</param>
        /// <returns>导出文件的二进制流（Excel）</returns>
        public async Task<byte[]> ExportAsync(string incomingInspectionCode = null, string batch = null, string testingResult = null, string testingPerson = null, string productName = null, DateTime? incomingDate = null, DateTime? testingDate = null)
        {
            var query = await _incomingInspectionrepository.GetQueryableAsync();
            if (!string.IsNullOrWhiteSpace(incomingInspectionCode))
                query = query.Where(x => x.IncomingInspectionCode.Contains(incomingInspectionCode));
            if (!string.IsNullOrWhiteSpace(batch))
                query = query.Where(x => x.Batch.Contains(batch));
            if (!string.IsNullOrWhiteSpace(testingResult))
                query = query.Where(x => x.TestingResult == testingResult);
            if (!string.IsNullOrWhiteSpace(testingPerson))
                query = query.Where(x => x.TestingPerson.Contains(testingPerson));
            if (!string.IsNullOrWhiteSpace(productName))
                query = query.Where(x => x.ProductName.Contains(productName));
            if (incomingDate.HasValue)
                query = query.Where(x => x.IncomingDate.Date == incomingDate.Value.Date);
            if (testingDate.HasValue)
                query = query.Where(x => x.TestingDate.Date == testingDate.Value.Date);
            var items = await query.OrderByDescending(x => x.Id).ToListAsync();

            using (var workbook = new XLWorkbook())
            {
                var worksheet = workbook.Worksheets.Add("来料检验数据");
                // 表头
                worksheet.Cell(1, 1).Value = "ID";
                worksheet.Cell(1, 2).Value = "来料检验单编号";
                worksheet.Cell(1, 3).Value = "来料检验单名称";
                worksheet.Cell(1, 4).Value = "供应商简称";
                worksheet.Cell(1, 5).Value = "供应商批次号";
                worksheet.Cell(1, 6).Value = "产品物料编号";
                worksheet.Cell(1, 7).Value = "产品物料名称";
                worksheet.Cell(1, 8).Value = "接收数量";
                worksheet.Cell(1, 9).Value = "检测数量";
                worksheet.Cell(1, 10).Value = "不合格数";
                worksheet.Cell(1, 11).Value = "检测结果";
                worksheet.Cell(1, 12).Value = "来料日期";
                worksheet.Cell(1, 13).Value = "检测日期";
                worksheet.Cell(1, 14).Value = "检测人员";
                worksheet.Cell(1, 15).Value = "单据状态";
                // 数据
                int row = 2;
                foreach (var item in items)
                {
                    worksheet.Cell(row, 1).Value = item.Id;
                    worksheet.Cell(row, 2).Value = item.IncomingInspectionCode;
                    worksheet.Cell(row, 3).Value = item.IncomingInspectionName;
                    worksheet.Cell(row, 4).Value = item.IncomingInspectionJName;
                    worksheet.Cell(row, 5).Value = item.Batch;
                    worksheet.Cell(row, 6).Value = item.ProductCode;
                    worksheet.Cell(row, 7).Value = item.ProductName;
                    worksheet.Cell(row, 8).Value = item.ReceiveNum;
                    worksheet.Cell(row, 9).Value = item.TestingNum;
                    worksheet.Cell(row, 10).Value = item.UnqualifiedNum;
                    worksheet.Cell(row, 11).Value = item.TestingResult;
                    worksheet.Cell(row, 12).Value = item.IncomingDate.ToString("yyyy-MM-dd");
                    worksheet.Cell(row, 13).Value = item.TestingDate.ToString("yyyy-MM-dd");
                    worksheet.Cell(row, 14).Value = item.TestingPerson;
                    worksheet.Cell(row, 15).Value = item.State;
                    row++;
                }
                using (var stream = new System.IO.MemoryStream())
                {
                    workbook.SaveAs(stream);
                    return stream.ToArray();
                }
            }
        }
    }
}
